package com.ruoyi.framework.security;

import com.ruoyi.common.core.domain.entity.H5User;
import com.ruoyi.common.core.domain.model.H5LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.framework.web.service.app.H5UserDetailsService;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.Collections;

/**
 * 短信登录认证提供者，跳过密码校验
 */
public class SmsAuthenticationProvider implements AuthenticationProvider {

    private final H5UserDetailsService h5UserDetailsService;

    public SmsAuthenticationProvider(H5UserDetailsService h5UserDetailsService) {
        this.h5UserDetailsService = h5UserDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 1. 获取手机号（未认证令牌的principal是手机号）
        String phone = (String) authentication.getPrincipal();
        if (phone == null || phone.length() != 11) {
            throw new AuthenticationServiceException("手机号格式错误");
        }

        // 2. 调用已有H5UserDetailsService查询用户（复用逻辑，无需重复写查询）
        H5LoginUser h5LoginUser = (H5LoginUser) h5UserDetailsService.loadUserByUsername(phone);
        H5User user = h5LoginUser.getH5User();

        // 3. 校验用户状态（H5UserDetailsService已校验，此处兜底）
        if ("1".equals(user.getStatus())) {
            throw new ServiceException("账号已禁用");
        }

        // 4. 封装权限（与密码登录保持一致，给H5角色）
        GrantedAuthority authority = new SimpleGrantedAuthority("H5");
        return new SmsAuthenticationToken(h5LoginUser, Collections.singletonList(authority));
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return SmsAuthenticationToken.class.isAssignableFrom(authentication);
    }
}